#include "android_utility.h"
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/bitmap.h>
#include <gles_utility.h>
#include <cstring>
#include <malloc.h>

void glesGetTextForAsset(JNIEnv *env, jobject assetManager, const char *filename, char *ret) {
    AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
    AAsset *asset = AAssetManager_open(mgr, filename, AASSET_MODE_BUFFER);
    if (!asset) {
        LOGE("open asset file %s failure.", filename);
        return;
    }
    auto len = AAsset_getLength(asset);
    char *buf = static_cast<char *>(malloc(len));
    memset(buf, 0, strlen(buf));
    AAsset_read(asset, buf, len);
    strcpy(ret, buf);
    if (!ret) {
        LOGE("get file %s text buffer is failure.", filename);
        return;
    }
    LOGI("file %s text buffer -> %s", filename, ret);
    free(buf);
    AAsset_close(asset);
}

uint glesLoadSingleTexture2D(JNIEnv *env, jobject bitmap, AndroidBitmapInfo *bmpInfo) {
    GLuint texIds[1];
    glGenTextures(1, texIds);
    if (texIds[0] == 0) {
        LOGE("generate a new OpenGL texture object failure.");
        return GL_FALSE;
    }
    void *pixels = nullptr;
    if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
        glDeleteTextures(1, texIds);
        glBindTexture(GL_TEXTURE_2D, GL_NONE); // unbind from the texture
        LOGE("get bitmap pixel address failure.");
        return GL_FALSE;
    }
    glBindTexture(GL_TEXTURE_2D, texIds[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    auto *info = (AndroidBitmapInfo *) (malloc(sizeof(AndroidBitmapInfo)));
    AndroidBitmap_getInfo(env, bitmap, info);
    LOGI("bitmap info -> width:%d,height:%d,stride:%d,format:%d,flags:%d", info->width,
         info->height, info->stride, info->format, info->flags);
    if (bmpInfo) memcpy(bmpInfo, info, sizeof(AndroidBitmapInfo));
    switch (info->format) {
        case ANDROID_BITMAP_FORMAT_A_8:
            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, info->width, info->height, 0, GL_ALPHA,
                         GL_UNSIGNED_BYTE, pixels);
            break;
        case ANDROID_BITMAP_FORMAT_RGB_565:
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, info->width, info->height, 0, GL_RGB,
                         GL_UNSIGNED_SHORT_5_6_5, pixels);
            break;
        case ANDROID_BITMAP_FORMAT_RGBA_4444:
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info->width, info->height, 0, GL_RGBA,
                         GL_UNSIGNED_SHORT_4_4_4_4, pixels);
            break;
        case ANDROID_BITMAP_FORMAT_RGBA_8888:
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info->width, info->height, 0, GL_RGBA,
                         GL_UNSIGNED_BYTE, pixels);
            break;
        case ANDROID_BITMAP_FORMAT_NONE:
        default:
            glDeleteTextures(1, texIds);
            glBindTexture(GL_TEXTURE_2D, 0); // unbind from the texture
            free(info);
            AndroidBitmap_unlockPixels(env, bitmap);
            return GL_FALSE;
    }
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, GL_NONE); // unbind from the texture
    AndroidBitmap_unlockPixels(env, bitmap);
    free(info);
    return texIds[0];
}